-module(dsn_parser).

-author("zhuiyi9009@163.com").

-export([parse_dsn/1]).

%% "test:test@127.0.0.1:3306/test_1?charset=utf8&abc=100"
parse_dsn(DSN) ->
    case string:split(DSN, "/", leading) of
        [Userinfo, DBQuery] ->
            {User, Password, Net, Addr} = parse_userinfo(Userinfo),
            {DBName, Params} = parse_dbquery(DBQuery),
            {ok, {User, Password, Net, Addr, DBName, Params}};
        _ ->
            {error, invalid_dsn}
    end.

parse_userinfo(Userinfo) ->
    case string:split(Userinfo, "@", trailing) of
        [UserPass, NetAddr] ->
            {User, Password} = parse_userpass(UserPass),
            {Net, Addr} = parse_netaddr(NetAddr),
            {User, Password, Net, Addr};
        _ ->
            {undefined, undefined, undefined, undefined}
    end.

parse_userpass(UserPass) ->
    case string:split(UserPass, ":", all) of
        [User, Password] -> {User, Password};
        [User] -> {User, undefined}
    end.

parse_netaddr(NetAddr) ->
    case string:split(NetAddr, ":", all) of
        [Net, Addr] -> {Net, Addr};
        [Net] -> {Net, undefined}
    end.

parse_dbquery(DBQuery) ->
    case string:split(DBQuery, "?", trailing) of
        [DBName, Params] -> {DBName, parse_params(Params)};
        [DBName] -> {DBName, []}
    end.

parse_params(Params) ->
    lists:map(
        fun (Param) ->
            case string:split(Param, "=", all) of
                [Key, Value] -> {Key, Value}
            end
        end, string:split(Params, "&", all)).


